home *** CD-ROM | disk | FTP | other *** search
- /* Dump Bytes.
- * Dave Darrah, Lansdale, PA
- */
-
- #include <string.h>
-
- typedef unsigned short * usp;
-
- // For unknown reasons, Think generates more efficient code
- // for the critical *(usp)outputText = aTablePtr[byte]
- // instructions when register coloring is off. Go figure.
-
- #pragma options (honor_register,\
- !assign_registers,\
- !gopt_coloring)
-
- // Address registers are used for:
- // the "inputBytes" pointer, passed parameter.
- // the "outputText" pointer, passed parameter.
- // the "outputTextA" pointer, which points to where
- // the Ascii representation goes.
-
- // Data registers are used for:
- // "space", a holder of a space.
- // "byte", a temp area that holds a value we want to
- // "burst" to ascii.
- // "eCntr, gCntr", counters used for two loops.
- // Pointer to "aTable": "aTablePtr". Think assigns the
- // last data reg to it.
-
- unsigned short DumpBytes(inputBytes,
- outputText,
- numInputBytes,
- maxOutputBytes,
- width,
- grouping)
-
- register Ptr inputBytes;
- register Ptr outputText;
- unsigned short numInputBytes;
- unsigned short maxOutputBytes;
- unsigned short width;
- unsigned short grouping;
- {
-
- register Byte space=' ';
- register Byte byte;
- register unsigned short eCntr,gCntr;
-
- register Ptr outputTextA;
-
- unsigned short dispValue=0;
- // This is the hex value of what's printed at the
- // beginning of each line.
-
- unsigned short groupsPerLine,lineLength,extras,
- numberOfLines,asciiOffset,
- lastLineLength;
-
- Boolean truncated=FALSE;
- Ptr saveOutputText=outputText;
-
- // 256 entry (512 byte) ascii table. This table will be
- // indexed by the byte value, to return the two-char entry
- // that is the character representation of that byte. See
- // note later about how Think generates this table.
-
- static char aTable[] = "\
- 000102030405060708090A0B0C0D0E0F\
- 101112131415161718191A1B1C1D1E1F\
- 202122232425262728292A2B2C2D2E2F\
- 303132333435363738393A3B3C3D3E3F\
- 404142434445464748494A4B4C4D4E4F\
- 505152535455565758595A5B5C5D5E5F\
- 606162636465666768696A6B6C6D6E6F\
- 707172737475767778797A7B7C7D7E7F\
- 808182838485868788898A8B8C8D8E8F\
- 909192939495969798999A9B9C9D9E9F\
- A0A1A2A3A4A5A6A7A8A9AAABACADAEAF\
- B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF\
- C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF\
- D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF\
- E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF\
- F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF";
-
- register usp aTablePtr=(usp)&aTable;
- // Think gives aTablePtr a data register,
- // and it actually helps!
-
- /*********************************************************/
-
-
-
- /**********************************************************/
-
- // That's it for local variables, first, let's initialize
- // a few variables and preflight the output length.
-
- // Because of some flukie I haven't been able to scope
- // out (a possible Think bug?), the last value (the
- // right "F" in "FF") of aTable is hex 0. Why? Don't
- // know. Oh well, let's just roll with the punch.
-
- aTable[511] = 'F';
-
-
- // Calculate number of groups per line.
-
- groupsPerLine = width/grouping;
-
-
- // Calculate output line length.
-
- lineLength = width*3 + groupsPerLine + 7;
- // 2 for hex representation, 1 for ascii;
- // 1 for each space that follows a group;
- // 4 for disp, a colon, space and return.
-
-
- // Calculate offset from outputText where ascii goes.
-
- asciiOffset = lineLength - width - 1;
-
-
- // Calculate the number of full lines of output.
-
- numberOfLines = numInputBytes/width;
-
-
- // Calculate the number of bytes left over after all
- // complete lines are done.
-
- extras = numInputBytes % width;
-
-
- // Calculate the number of bytes this line takes.
-
- lastLineLength = asciiOffset + extras;
-
-
- // Reduce numberOfLines if output would run past
- // maxOutputBytes. Just dump the number of full
- // lines that fit in maxOutputBytes.
-
- if ( (lineLength * (unsigned long)numberOfLines) +
- lastLineLength > maxOutputBytes) {
- numberOfLines = maxOutputBytes/lineLength;
- extras = 0;
- truncated = TRUE;
- }
-
-
-
- /*******************************************************/
-
- // Initialization and preflighting done.
- // It's time to process the input.
-
- numberOfLines++;
- while (--numberOfLines) { // Do each full line.
-
- outputTextA = outputText+asciiOffset;
-
- // Displacement value goes first.
- byte = dispValue>>8; // left byte of disp
-
- *(usp)outputText = aTablePtr[byte];
- outputText += 2;
-
- byte = dispValue; // right byte of disp
-
- *(usp)outputText = aTablePtr[byte];
- outputText += 2;
-
- *(usp)outputText = ': ';
- outputText += 2;
-
- dispValue += width;
-
- // Now do "groupsPerLine" sets of hex expansions.
- eCntr = groupsPerLine;
- do { // each of the "groupsPerLine" groups.
-
- gCntr = grouping;
- do { // each of the "grouping" bytes.
-
- byte = *inputBytes++;
- *(usp)outputText = aTablePtr[byte];
- outputText += 2;
-
- // Do the ascii.
- if (byte < space || byte > 0x7E)
- *outputTextA++ = '.';
- else
- *outputTextA++ = byte;
-
- } while (--gCntr); // End "grouping bytes" loop
-
- *outputText++ = space; // Space after each group
-
- } while (--eCntr); // End "groups per line" loop
-
- *outputTextA++ = '\r';
-
- // Point to beginning of next line.
- outputText = outputTextA;
-
- } // End of "lines" loop.
-
-
-
- // Now to worry, if necessary, about dribble left over.
- // A lot of code duplication, but what the hey!
-
- if ( extras ) {
- // Space output line.
- memset(outputText,space,lineLength);
-
- outputTextA = outputText+asciiOffset;
-
- // Displacement value goes first.
- byte = dispValue>>8; // left byte of disp
-
- *(usp)outputText = aTablePtr[byte];
- outputText += 2;
-
- byte = dispValue; // right byte of disp
-
- *(usp)outputText = aTablePtr[byte];
- outputText += 2;
-
- *outputText = ':'; // space is already there.
- outputText += 2;
-
- // Now do "groupsPerLine" sets of hex expansions.
- eCntr = groupsPerLine;
- do { // each of the "groupsPerLine" groups.
-
- gCntr = grouping;
- do { // each of the "grouping" bytes.
-
- byte = *inputBytes++;
- *(usp)outputText = aTablePtr[byte];
- outputText += 2;
-
- // Do the ascii.
- if (byte < space || byte > 0x7E)
- *outputTextA++ = '.';
- else
- *outputTextA++ = byte;
-
- if (!--extras)
- goto AllDone; // Nasty termination when
- // we've done 'em all.
-
- } while (--gCntr); // End "bytes in group" loop
-
- // skip past space after each group.
- *outputText++;
-
- } while (--eCntr); // End of groups per line loop.
-
- } // end if
-
- AllDone:
-
- if (truncated)
- return 0;
- else
- return(outputTextA - saveOutputText);
- }
-